<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>html5动感的火焰燃烧动画特效</title>
    <style>
        body {
            background: #000;
        }
        
        .wrapper {
            margin: 20px auto 5px;
            text-align: center;
        }
        
        canvas {
            width: 100%;
            height: 100%;
        }
    </style>
</head>

<body>
    <div class="wrapper">
        <canvas id="surface"></canvas>
    </div>
    <script>
        window.onload = function() {

            // set canvas drawing surface 
            let space = document.getElementById("surface");
            let canvs = document.getElementsByClassName("wrapper")[0];
            let surface = space.getContext('2d');
            surface.scale(1, 1);

            //   set particles
            let particles = [];
            let particle_count = 150;
            for (let i = 0; i < particle_count; i++) {
                particles.push(new particle());
            }
            let time = 0;
            // set wrapper and canvas items size 
            var canvasWidth = 320;
            var canvasHeight = 480;

            canvs.style.width = canvasWidth + 'px';
            canvs.style.height = canvasHeight + 'px';

            space.style.width = canvasWidth + 'px';
            space.style.height = canvasHeight + 'px';

            window.requestAnimationFrame = (function() {
                return window.requestAnimationFrame ||
                    window.webkitRequestAnimationFrame ||
                    window.mozRequestAnimationFrame ||
                    function(callback) {
                        window.setTimeout(callback, 6000 / 60);
                    }
            })();

            function particle() {
                this.speed = {
                    x: -1 + Math.random() * 2,
                    y: -5 + Math.random() * 5
                };
                canvasWidth = (document.getElementById("surface").width);
                canvasHeight = (document.getElementById("surface").height);
                this.location = {
                    x: canvasWidth / 2,
                    y: (canvasHeight / 2) + 35
                }
                this.radius = 0.5 + Math.random() * 1;
                this.life = 10 + Math.random() * 10;
                this.death = this.life;

                // 火焰颜色
                this.r = 255;
                this.g = Math.round(Math.random() * 155);
                this.b = 0;
            }

            function ParticleAnimation() {
                surface.globalCompositeOperation = "source-over";
                surface.fillStyle = "#000";
                surface.fillRect(0, 0, canvasWidth, canvasHeight);
                surface.globalCompositeOperation = "lighter";

                for (let i = 0; i < particles.length; i++) {
                    let p = particles[i];
                    surface.beginPath();

                    p.opacity = Math.round(p.death / p.life * 100) / 100

                    let gradient = surface.createRadialGradient(p.location.x, p.location.y, 0, p.location.x, p.location.y, p.radius);
                    gradient.addColorStop(0, `rgba(${p.r},${p.g},${p.b},${p.opacity}`);
                    gradient.addColorStop(0.5, `rgba(${p.r},${p.g},${p.b},${p.opacity}`);
                    gradient.addColorStop(1, `rgba(${p.r},${p.g},${p.b},${p.opacity}`);
                    surface.fillStyle = gradient;
                    surface.arc(p.location.x, p.location.y, p.radius, Math.PI * 2, false);
                    surface.fill();
                    p.death--;
                    p.radius++;
                    p.location.x += (p.speed.x);
                    p.location.y += (p.speed.y);

                    // regenerate particles
                    if (p.death < 0 || p.radius < 0) {
                        // a brand new particle replacing the dead one 
                        particles[i] = new particle();
                    }

                }
                requestAnimationFrame(ParticleAnimation);
            }
            ParticleAnimation();
        }
    </script>
</body>

</html>